package kr.co.bettersoft.carrotmemberstore.common;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import kr.co.bettersoft.carrotmemberstore.domain.CheckMileageMerchant;
import kr.co.bettersoft.carrotmemberstore.domain.CheckMileageMileage;
import kr.co.bettersoft.carrotmemberstore.domain.PostAddress;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.util.Log;

public class CarrotMemberStoreRest {

	String TAG = "CarrotMemberStoreRest";

	// 서버 통신
	int responseCode = 0;
	String controllerName ="";
	String methodName ="";
	String serverName = CommonConstant.serverName;
	URL postUrl2 = null;
	HttpURLConnection connection2 = null;
	int isRunning = 0;		// 통신 도중 중복 호출을 방지하기 위함.
	String fullUrl = "";
	String inputJson = "";
	JSONObject jsonObject;
	JSONObject jsonObj;
	JSONArray jsonArray2;
	JSONObject obj = new JSONObject();

	String nowTime = "";	// 현시각

	// 결과
	String callResult = "";
	String tempstr = "";
	int max;

	// 우편번호 검색용
	String zipCodeURL;
	String searchWord;
	String searchResult;
	String ZIPCODE;			// zipcode , sido, bunji, GUGUN
	String SIDO ;			// zipcode , sido, bunji, GUGUN
	String GUGUN ;			// zipcode , sido, bunji, GUGUN
	String DONG ;			// zipcode , sido, bunji, GUGUN
	String BUNJI ;			// zipcode , sido, bunji, GUGUN
	// ajax 통신용.
	public  HttpURLConnection m_con ;
	public String m_request ;
	OutputStream out = null;
	
	
	// 가맹점 정보 저장
	CheckMileageMerchant checkMileageMerchant = new CheckMileageMerchant(); 
	// 마일리지 정보 저장
	CheckMileageMileage checkMileageMileage = new CheckMileageMileage(); 

	// 마일리지 리스트
	public ArrayList<CheckMileageMileage> checkMileageMileageEntries1 = new ArrayList<CheckMileageMileage>();	// 1차적으로 조회한 결과. 
	List<CheckMileageMileage> checkMileageMileageEntriesFn = new ArrayList<CheckMileageMileage>();				// 최종 산출물
	// 우편번호 리스트
	List<PostAddress> postAddressEntriesFn;			// 최종 산출물
	
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////	
	// 서버 통신

	/**
	 * RestLogin
	 *   로그인한다
	 * @param checkMileageMerchantParam 
	 * @return  String
	 */
	public String RestLogin(CheckMileageMerchant checkMileageMerchantParam ){

		checkMileageMerchant = checkMileageMerchantParam;

		nowTime = CommonUtils.getNowDate();
		// 파라미터 셋팅
		controllerName = "checkMileageMerchantController";
		methodName = "login";	
		fullUrl = serverName+"/"+controllerName+"/"+methodName;
		obj = new JSONObject();
		try{		 
			obj.put("merchantId", checkMileageMerchant.getMerchantId());		// 아디
			obj.put("password", checkMileageMerchant.getPassword());			// 비번
			obj.put("activateYn", "Y");				// 활성화 여부
		}catch(Exception e){
			e.printStackTrace();
		}
		inputJson = "{\"checkMileageMerchant\":" + obj.toString() + "}";

		// 서버호출 메소드 실행
		callResult = callServerMethod(fullUrl, inputJson);

		// 서버 호출 결과 처리
		if(callResult.equals("S")){
		}
		return callResult;
	}

	/**
	 * RestSelectMerchantInformation
	 *   가맹점 정보 가져온다
	 * @return  String
	 */
	public String RestSelectMerchantInformation(CheckMileageMerchant checkMileageMerchantParam ){

		checkMileageMerchant = checkMileageMerchantParam;

		nowTime = CommonUtils.getNowDate();
		// 파라미터 셋팅
		controllerName = "checkMileageMerchantController";
		methodName = "selectMerchantInformation";
		fullUrl = serverName+"/"+controllerName+"/"+methodName;
		obj = new JSONObject();
		try{		 
			obj.put("merchantId", checkMileageMerchant.getMerchantId());		// 아디
			obj.put("activateYn", "Y");
		}catch(Exception e){
			e.printStackTrace();
		}
		inputJson = "{\"checkMileageMerchant\":" + obj.toString() + "}";

		// 서버호출 메소드 실행
		callResult = callServerMethod(fullUrl, inputJson);

		// 서버 호출 결과 처리
		if(callResult.equals("S")){
		}
		return callResult;
	}




	/**
	 * RestCheckMileageExist
	 *     고객 정보를 가져온다.
	 * @return  String
	 */
	public String RestCheckMileageExist(CheckMileageMileage checkMileageMileageParam ){

		checkMileageMileage = checkMileageMileageParam;

		nowTime = CommonUtils.getNowDate();
		// 파라미터 셋팅
		controllerName = "checkMileageMileageController";
		methodName = "checkMileageExist";
		fullUrl = serverName+"/"+controllerName+"/"+methodName;
		obj = new JSONObject();
		try{		 
			obj.put("checkMileageMembersCheckMileageId", checkMileageMileage.getCustomerId());
			obj.put("checkMileageMerchantsMerchantId", checkMileageMileage.getMerchantId());
			obj.put("activateYn", "Y");
		}catch(Exception e){
			e.printStackTrace();
		}
		inputJson = "{\"checkMileageMileage\":" + obj.toString() + "}";

		// 서버호출 메소드 실행
		callResult = callServerMethod(fullUrl, inputJson);

		// 서버 호출 결과 처리
		if(callResult.equals("S")){
		}
		return callResult;
	}


	/**
	 * RestRegisterMileage
	 *   마일리지를 적립한다.
	 * @return  String
	 */
	public String RestRegisterMileage(CheckMileageMileage checkMileageMileageParam ){

		checkMileageMileage = checkMileageMileageParam;

		nowTime = CommonUtils.getNowDate();
		// 파라미터 셋팅
		controllerName = "checkMileageMileageController";
		methodName = "registerMileage";
		fullUrl = serverName+"/"+controllerName+"/"+methodName;
		obj = new JSONObject();
		try{		 
			obj.put("checkMileageMembersCheckMileageId", checkMileageMileage.getCustomerId());
			obj.put("checkMileageMerchantsMerchantId", checkMileageMileage.getMerchantId());
			obj.put("modifyDate", nowTime);		// 수정일 : 현재 시각
			obj.put("registerDate", nowTime);	// 등록일 : 현재 시각
			obj.put("mileage", checkMileageMileage.getMileage());			// 마일리지: 기존 마일리지
			obj.put("bill", checkMileageMileage.getBill());					// 금액 : 결재 금액
			obj.put("content", "AMASS");					// 내용 : AMASS		   적립 또는 신규.
			obj.put("activateYn", "Y");
		}catch(Exception e){
			e.printStackTrace();
		}
		inputJson = "{\"checkMileageMileage\":" + obj.toString() + "}";

		// 서버호출 메소드 실행
		callResult = callServerMethod(fullUrl, inputJson);

		// 서버 호출 결과 처리
		if(callResult.equals("S")){
			try{
				jsonObject = new JSONObject(tempstr);
				JSONObject jsonobj2 = jsonObject.getJSONObject("checkMileageMileage");
				callResult = jsonobj2.getString("result"); 
			}catch(Exception e){
				e.printStackTrace();
			}
		}
		return callResult;
	}

	/**
	 * RestRegisterCashMileage
	 *   현금 마일리지를  적립한다.
	 * @return  String
	 */
	public String RestRegisterCashMileage(CheckMileageMileage checkMileageMileageParam ){

		checkMileageMileage = checkMileageMileageParam;

		nowTime = CommonUtils.getNowDate();
		// 파라미터 셋팅
		controllerName = "checkMileageMileageController";
		methodName = "registerMileageCash";
		fullUrl = serverName+"/"+controllerName+"/"+methodName;
		obj = new JSONObject();
		try{		 
			obj.put("checkMileageMembersCheckMileageId", checkMileageMileage.getCustomerId());
			obj.put("checkMileageMerchantsMerchantId", checkMileageMileage.getMerchantId());
			obj.put("modifyDate", nowTime);		// 수정일 : 현재 시각
			obj.put("registerDate", nowTime);	// 등록일 : 현재 시각
			obj.put("mileage", checkMileageMileage.getMileage());			// 마일리지: 기존 마일리지
			obj.put("bill", checkMileageMileage.getBill());					// 금액 : 결재 금액
			obj.put("content", "AMASS");					// 내용 : AMASS		   적립 또는 신규.
			obj.put("activateYn", "Y");
		}catch(Exception e){
			e.printStackTrace();
		}
		inputJson = "{\"checkMileageMileage\":" + obj.toString() + "}";

		// 서버호출 메소드 실행
		callResult = callServerMethod(fullUrl, inputJson);

		// 서버 호출 결과 처리
		if(callResult.equals("S")){
			try{
				jsonObject = new JSONObject(tempstr);
				JSONObject jsonobj2 = jsonObject.getJSONObject("checkMileageMileage");
				callResult = jsonobj2.getString("result"); 
			}catch(Exception e){
				e.printStackTrace();
			}
		}
		return callResult;
	}


	/**
	 * RestUpdateMileage
	 *    마일리지를 사용한다.
	 * @return  String
	 */
	public String RestUpdateMileage(CheckMileageMileage checkMileageMileageParam ){

		checkMileageMileage = checkMileageMileageParam;

		nowTime = CommonUtils.getNowDate();
		// 파라미터 셋팅
		controllerName = "checkMileageMileageController";
		methodName = "updateMileage";
		fullUrl = serverName+"/"+controllerName+"/"+methodName;
		obj = new JSONObject();
		try{		 
			obj.put("checkMileageMembersCheckMileageId", checkMileageMileage.getCustomerId());
			obj.put("checkMileageMerchantsMerchantId", checkMileageMileage.getMerchantId());
			obj.put("modifyDate", nowTime);		// 수정일 : 현재 시각
			obj.put("registerDate", nowTime);	// 등록일 : 현재 시각
			obj.put("mileage", checkMileageMileage.getMileage());			// 마일리지: 기존 마일리지
			obj.put("spendMileage", checkMileageMileage.getBill());					// 금액 : 결재 금액
			obj.put("content", "CHECK");					// 내용 : AMASS		   적립 또는 신규.
			obj.put("activateYn", "Y");
		}catch(Exception e){
			e.printStackTrace();
		}
		inputJson = "{\"checkMileageMileage\":" + obj.toString() + "}";

		// 서버호출 메소드 실행
		callResult = callServerMethod(fullUrl, inputJson);

		// 서버 호출 결과 처리
		if(callResult.equals("S")){
			try{
				jsonObject = new JSONObject(tempstr);
				JSONObject jsonobj2 = jsonObject.getJSONObject("checkMileageMileage");
				callResult = jsonobj2.getString("result"); 
			}catch(Exception e){
				e.printStackTrace();
			}
		}
		return callResult;
	}


	/**
	 * RestSelectMerchantMemberMileageList
	 *    고객 마일리지 리스트를 가져온다.
	 * @return  String
	 */
	public String RestSelectMerchantMemberMileageList(CheckMileageMileage checkMileageMileageParam ){

		checkMileageMileage = checkMileageMileageParam;

		nowTime = CommonUtils.getNowDate();
		// 파라미터 셋팅
		controllerName = "checkMileageMileageController";
		methodName = "selectMerchantMemberMileageList";
		fullUrl = serverName+"/"+controllerName+"/"+methodName;
		obj = new JSONObject();
		try{		 
			obj.put("checkMileageMerchantsMerchantId", checkMileageMileage.getMerchantId());		// 전달받은 가맹점 아이디 그대로 사용
			obj.put("activateYn", "Y");
		}catch(Exception e){
			e.printStackTrace();
		}
		inputJson = "{\"checkMileageMileage\":" + obj.toString() + "}";

		// 서버호출 메소드 실행
		callResult = callServerMethod(fullUrl, inputJson);

		// 서버 호출 결과 처리
		if(callResult.equals("S")){
			try {
				jsonArray2 = new JSONArray(tempstr);
				max = jsonArray2.length();
			} catch (JSONException e1) {
				e1.printStackTrace();
				callResult = "F";
			}
			if(max>0){
				checkMileageMileageEntries1 = new ArrayList<CheckMileageMileage>(max);		
				for ( int i = 0; i < max; i++ ){
					JSONObject jsonObj;
					try {
						jsonObj = jsonArray2.getJSONObject(i).getJSONObject("checkMileageMileage");	// 대소문자 주의
						String tempCustomerId="";
						String tempCustomerMileage="";
						String tempCustomerUpdateDate="";
						String tempCustomerRegisterDate="";
						String tempCustomerPhoneNumber="";
						try{
							tempCustomerId = jsonObj.getString("checkMileageMembersCheckMileageId");
						}catch(Exception e1){ tempCustomerId = ""; }
						try{
							tempCustomerMileage = jsonObj.getString("mileage");
						}catch(Exception e1){ tempCustomerMileage = ""; }
						try{
							tempCustomerUpdateDate = jsonObj.getString("modifyDate");
							if(tempCustomerUpdateDate!=null &&(tempCustomerUpdateDate.length()>16)){
								tempCustomerUpdateDate = tempCustomerUpdateDate.substring(0, 16);
							}
						}catch(Exception e1){ tempCustomerUpdateDate = ""; }
						try{
							tempCustomerRegisterDate = jsonObj.getString("registerDate");
							if(tempCustomerRegisterDate!=null &&(tempCustomerRegisterDate.length()>16)){
								tempCustomerRegisterDate = tempCustomerRegisterDate.substring(0, 16);
							}
						}catch(Exception e1){ tempCustomerRegisterDate = ""; }
						try{
							tempCustomerPhoneNumber = jsonObj.getString("phoneNumber");
						}catch(Exception e1){ tempCustomerPhoneNumber = ""; }

						checkMileageMileageEntries1.add(
								new CheckMileageMileage(
										tempCustomerId,
										tempCustomerMileage,
										tempCustomerUpdateDate,		
										tempCustomerRegisterDate,
										tempCustomerPhoneNumber
								)
						);
					} catch (Exception e) {
						e.printStackTrace();
						callResult = "F";
					}	
				}
				checkMileageMileageEntriesFn = checkMileageMileageEntries1;
			}
		}
		return callResult;
	}


	/**
	 * RestRequestAddress
	 *     우편번호 정보 요청한다
	 * @param searchWordParam 
	 * @param zipCodeURLParam 
	 * @return  String
	 */
	public String RestRequestAddress(String zipCodeURLParam, String searchWordParam ){
		zipCodeURL = zipCodeURLParam;
		searchWord = searchWordParam;
		try {
			callResult = "S";
			searchResult = request(new  URL(zipCodeURL),searchWord);
			JSONArray jsonArray2 = null;
			try {
				jsonArray2 = new JSONArray(searchResult);
			} catch (JSONException e1) {
				e1.printStackTrace();
			}
			int max = jsonArray2.length();
			Log.d(TAG,"max:"+max);	
			postAddressEntriesFn = new ArrayList<PostAddress>(max);
			try {
				if(max>0){
					// 받은 데이터를 도메인리스트에 담는다.
					for ( int i = 0; i < max; i++ ){
						JSONObject jsonObj = jsonArray2.getJSONObject(i).getJSONObject("zipcode");		// 대소문자 주의
						ZIPCODE  = jsonObj.getString("ZIPCODE");			// zipcode , sido, bunji, GUGUN			
						SIDO  = jsonObj.getString("SIDO");			// zipcode , sido, bunji, GUGUN
						GUGUN  = jsonObj.getString("GUGUN");			// zipcode , sido, bunji, GUGUN
						DONG  = jsonObj.getString("DONG");			// zipcode , sido, bunji, GUGUN
						BUNJI  = jsonObj.getString("BUNJI");			// zipcode , sido, bunji, GUGUN
						//							Log.d(TAG,ZIPCODE+" "+SIDO+" "+GUGUN+" "+DONG+" "+BUNJI);
						PostAddress tmpPostAddress = new PostAddress(ZIPCODE, SIDO, GUGUN, DONG, BUNJI);
						postAddressEntriesFn.add(tmpPostAddress);
					}
				}else{
					Log.d(TAG,"no data");
				}
			} catch (JSONException e) {
				e.printStackTrace();
				callResult = "F";
			}
		} catch (Exception e) {
			e.printStackTrace();
			callResult = "F";
		}
		return callResult;
	}
	/**
	 * request
	 * 우편번호 정보를 얻어온다(1단계)
	 *
	 * @param url
	 * @param searchWord
	 * @return getRequest
	 */
	public String request( URL url,  String searchWord ) throws IOException  {
		/// url에 연결
		m_con = (HttpURLConnection)url.openConnection( ) ;
		m_con.setRequestMethod( "POST" ) ;
		/// 인코딩 정의 HTTP방식으로 전송할때는 urlencoded방식으로 인코딩해서 전송해야한다.
		m_con.setRequestProperty( "Content-Type", "application/x-www-form-urlencoded" ) ;
		/// 인풋스트림 쓸거라고 지정
		m_con.setDoInput( true ) ;
		/// 데이터를 주소와 별개로 전송한다.
		m_con.setDoOutput( true ) ;      /// 아웃풋 스트림 쓰기위에 아웃풋을 true로 켬
		//	String paramstr = buildParameters( params ) ; /// 파라메터를 문자열로 치환
		String paramstr = "word="+searchWord ; /// 파라메터를 문자열로 치환
		out = m_con.getOutputStream( ) ;    /// 아웃풋 스트림 생성
		out.write(paramstr.getBytes( "UTF-8" ) ) ;  /// UTF-8포멧으로 변경해서 쓴다.
		out.flush( ) ;         /// 플러쉬~
		out.close( ) ;         /// 스트림 닫기
		Log.d( "-- gsLog ---", "post succes" ) ;   /// 로그출력
		return getRequest( ) ;	
	}
	/**
	 * getRequest
	 * 우편번호 정보를 얻어온다(2단계)
	 *
	 * @param 
	 * @param 
	 * @return m_request
	 */
	public String getRequest( ) throws UnsupportedEncodingException, IOException {
		InputStream in = null ;
		/// 받아온 데이터를 쓰기위한 스트림
		ByteArrayOutputStream bos = new ByteArrayOutputStream( ) ;
		/// 리퀘스트 데이터를 저장할 버퍼
		byte[] buf = new byte[2048];
		try
		{
			int k = 0 ; /// 읽은 라인수
			//		long ti = System.currentTimeMillis( ) ; /// == 시간 체크용 == 서버에 따라 리퀘스트 오는 시간이 매우 오래걸림
			in = m_con.getInputStream( ) ;       /// 인풋스트림 생성
			/// 루프를 돌면서 리퀘스트로 받은내용을 저장한다.
			while( true )
			{
				int readlen = in.read( buf ) ;
				if( readlen < 1 )
					break ;
				k += readlen ;
				bos.write( buf, 0, readlen ) ;
			}
			/// 리퀘스트 받은 내용을 UTF-8로 변경해서 문자열로 저장
			m_request = new String( bos.toByteArray( ), "UTF-8" ) ;
			return m_request;
		}
		catch (IOException e) 
		{
			/// 리퀘스트 받다가 에러가 나면 에러나면서 받은 메세지를 읽는다.
			if ( m_con.getResponseCode( ) == 500 ) 
			{
				/// 버퍼 리셋하고 에러값 받을 인풋스트림 생성해서 레어메세지 얻기
				bos.reset( ) ;
				InputStream err = m_con.getErrorStream( ) ;
				while( true ) 
				{
					int readlen = err.read( buf ) ;
					if ( readlen < 1 )
						break ;
					bos.write( buf, 0, readlen ) ;
				}
				/// 에러메세지를 문자열로 저장
				String output = new String( bos.toByteArray( ), "UTF-8" ) ;
				/// 읽은 에러메세지를 출력한다.
				System.err.println( output ) ;
			}
			m_request = "error" ;
			throw e ;
		} 
		finally /// 500에러도 아니면 그냥 접속 끊어버림.... 
		{
			if ( in != null )
				in.close( ) ;
			if ( m_con != null )
				m_con.disconnect( ) ;
			m_request = "error" ;
		}
		//return m_request ;
	}


	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	// 공용 서버 호출 메소드
	public String callServerMethod(String fullUrl, String inputJson){
		try{
			postUrl2 = new URL(fullUrl);
			connection2 = (HttpURLConnection) postUrl2.openConnection();
			connection2.setConnectTimeout(CommonConstant.serverConnectTimeOut);
			connection2.setDoOutput(true);
			connection2.setInstanceFollowRedirects(false);
			connection2.setRequestMethod("POST");
			connection2.setRequestProperty("Content-Type", "application/json");
			Thread.sleep(200);
			OutputStream os2 = connection2.getOutputStream();
			os2.write(inputJson.getBytes("UTF-8"));
			os2.flush();
			responseCode = connection2.getResponseCode();
			InputStream in =  connection2.getInputStream();
			if(responseCode==200 || responseCode==204){
				// 결과를 처리.
				BufferedReader reader = new BufferedReader(new InputStreamReader(in), 8192);
				StringBuilder builder = new StringBuilder();
				String line =null;
				try {
					while((line=reader.readLine())!=null){
						builder.append(line).append("\n");
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
				tempstr = builder.toString();
				callResult = "S";
			}else{
				Log.d(TAG,"Fail["+responseCode+"]");
				callResult="";
			}
		}catch(Exception e){ 
			e.printStackTrace();
			callResult="";
			initNetwork();
		}
		isRunning = 0;
		return callResult;
	}


	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////		
	// 처리 결과 반환 메소드

	// 고객 마일리지 리스트
	public List<CheckMileageMileage> getCheckMileageMileageEntriesFn(){
		return checkMileageMileageEntriesFn;
	}

	//우편번호 검색 결과
	public List<PostAddress> getPostAddressEntriesFn(){
		return postAddressEntriesFn;
	}
	
	// tempstr
	public String getTempstr(){
		return tempstr;
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////
	//유틸

	// 넷웍 초기화
	public void initNetwork(){
		if(connection2!=null){
			connection2.disconnect();
			connection2 = null;
		}
		postUrl2 = null;
	}
}
